<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0066)http://www.vovisoft.com/dotNET/Support/UnicodeBasic/NETUnicode.htm -->
<HTML><HEAD><TITLE>Using Unicode in .NET</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<META http-equiv=Content-Language content=vi>
<META content="MSHTML 5.50.4134.100" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId>
<META 
content="Visual Basic, VB Programming in Vietnamese, Vovisoft, VB.NET, dotNET, VB6, VB Tutorials, Learn Visual Basic, Internet, Unicode, Vietnamese VB tutorials, Database, Asp, Java, Javascript, VBscript, FrontPage 2000, XML, Ms Office 2000" 
name=keywords><LINK href="Can ban ve UNICODE tieng Viet_files/topbottom.css" 
type=text/css rel=stylesheet></HEAD>
<BODY leftMargin=0 marginheight="0" marginwidth="0">
<CENTER><A href="http://www.vovisoft.com/"><IMG height=77 alt="Logo of Vovisoft" 
src="Can ban ve UNICODE tieng Viet_files/vs-logo4_10.gif" width=102 border=0> 
</A><BR>
<H2><FONT face=Tahoma color=#800000>Dùng Unicode chữ Việt trong .NET 
</FONT></H2></CENTER>
<BLOCKQUOTE>
  <BLOCKQUOTE>
    <H3><FONT face=Tahoma color=green>Căn bản Unicode chữ Việt</FONT></H3>
    <H3><FONT face=Tahoma color=blue>ISO 10646 và Unicode</FONT></H3><FONT 
    face=Tahoma><B>ISO (International Standard Organisation) 10646</B> là tiêu 
    chuẩn quốc tế nhằm cung ứng đủ số ký tự để dùng cho mọi chữ của tất cả ngôn 
    ngữ trên thế giới. Thay vì dùng 8 bits để biểu diễn chỉ 255 dấu hiệu, bây 
    giờ người ta dùng đến 16 bits để có thể biểu diễn đến trên 65000 dấu 
    hiệu.<BR><BR>Hãy tưởng tượng một bài viết có thể chứa nhiều ngôn ngữ cùng 
    một lúc. Hay môt chương trình hiển thị các đề mục bằng ngôn ngữ địa phương, 
    vì khi chương trình khởi động nó nhận diện ra ngay là nó đang đuợc chạy ở xứ 
    nào bằng cách đọc <B>Locale</B> từ Windows .<BR><BR>Một trong những ưu điểm 
    của tiêu chuẩn nầy là sự cố gắng để xáp nhập các tiêu chuẩn 8 bit có sẵn để 
    không cần phải thay đổi chúng. Thật ra <B>ISO 10646</B> là tiêu chuẩn quốc 
    tế chính thức, còn <B>Unicode</B> thì được <A 
    href="http://www.unicode.org/">Unicode Consortium</A> (tập hợp đại diện các 
    công ty Tin Học lớn) soạn ra. Nhưng cả hai tiêu chuẩn gần như y hệt nhau khi 
    nói đến con số dùng để biểu diễn một chữ, con số nầy đuợc gọi là <B>code 
    point</B>. Thí dụ như code point của chữ <FONT size=+1><B>ả</B></FONT> là 
    <FONT size=+1><B>1EA3</B></FONT>, của chữ <FONT size=+1><B>ơ</B></FONT> là 
    <FONT size=+1><B>01A1</B></FONT>. Ðể biểu diễn một code point, tùy theo cách 
    encoding, có khi ta cần 1, 2, 3 hay 4 bytes .v.v., mỗi byte dùng cho code 
    point người ta không gọi là byte hay octet, mà lại gọi là <B>code unit</B>. 
    Thỉnh thoảng, Unicode được cập nhật hóa, và ấn bản mới nhất hiện giờ là 
    3.1.1.<BR><BR>ISO 10646 định nghĩa hai bộ <B>CCS (Coded Character Sets)</B>, 
    <B>UCS-2</B> và <B>UCS-4</B>. UCS-2 dùng 16 bits và là một phần nhỏ (subset) 
    của UCS-4.<BR>UCS-4 là một CCS dùng 31bits, chia thành 4 nhóm như sau: 
    <BLOCKQUOTE>
      <BLOCKQUOTE><FONT face=courier size=+1>
        <TABLE cellPadding=10 bgColor=#e8e8e8 border=2>
          <TBODY>
          <TR>
            <TD width="20%">7 bits</TD>
            <TD width="20%">8 bits</TD>
            <TD width="20%">8 bits</TD>
            <TD width="20%">8 bits</TD></TR>
          <TR>
            <TD><FONT color=magenta>1111111</FONT></TD>
            <TD><FONT color=blue>11111111</FONT></TD>
            <TD><FONT color=red>11111111</FONT></FONT></TD>
            <TD><FONT color=green>11111111</FONT></TD></TR>
          <TR>
            <TD><B>Group</B></TD>
            <TD><B>Plane</B></TD>
            <TD><B>Row</B></TD>
            <TD><B>Cell</B></TD></TR></TBODY></TABLE></FONT></BLOCKQUOTE></BLOCKQUOTE><BR>Cái 
    Plane đầu tiên của UCS-4 với giá trị Group=0, Plane=0 cũng là chính UCS-2. 
    Nó còn đuợc gọi là <B>BMP (Basic Multilingual Plane)</B>. <BR><BR>Code 
    points trong UCS thường được viết dưới dạng <B>u+????</B>, mà ???? là con số 
    hexadecimal của code point. Characters có giá trị trong khoảng từ 
    <B>u+0021</B> đến <B>u+007E</B> thì giống như <B>ASCII</B> và các characters 
    trong khoảng từ <B>u+00A0</B> đến <B>u+00FF</B> thì giống như <B>ISO 
    8859-1</B>. Do đó rất dễ cho ta hoán chuyển giữa ASCII hay ISO 8859-1 với 
    UCS. <BR>Unicode (version 3.0.1) thì dùng 20bit subset của UCS-4 làm Coded 
    Character Set. </FONT>
    <H3><FONT face=Tahoma color=blue>Những Character Encoding 
    Schemes</FONT></H3><FONT face=Tahoma>Có vài Character Encoding Schemes được 
    đưa ra dùng: đó là <B>UTF-8, UTF-16, UTF-16LE, và UTF-16BE</B>. <B>UTF</B> 
    là viết tắt chữ <B>Unicode Transformation Format</B>.</FONT><BR>
    <H4><FONT face=Tahoma color=blue>UTF-16</FONT></H4><FONT face=Tahoma>UTF-16 
    là một cách encoding dùng 20bit Unicode. Các characters trong BMP được diễn 
    tả bằng cách dùng giá trị 16bit của code point trong Unicode CCS. Có hai 
    cách để viết 16bit value trong một dòng (stream) 8bit . Có lẽ bạn đã nghe 
    qua chữ <B>endian</B>. <B>Big Endian</B> có nghĩa là cho Most Significant 
    Byte đi trước, tức là nằm bên trái - do đó ta có <B>UTF-16BE</B>. Còn 
    <B>Little Endian</B> thì ngược lại, tức là Least Significant Byte đi trước - 
    do đó ta có <B>UTF-16LE</B>. Thí dụ, giá trị 16bit của con số <B>Hex1234</B> 
    được viết là <B>Hex12 Hex34</B> trong big endian và <B>Hex34 Hex12</B> trong 
    little endian.<BR><BR>Những characters không nằm trong BMP đuợc biểu diễn 
    bằng cách dùng <B>surrogate pair</B> (cặp thay thế). Code points có giá trị 
    từ u+D800 đến u+DFFF được dành riêng ra để dùng cho mục đích nầy. Trước hết, 
    một code point có 20 bits được phân ra làm hai nhóm 10 bits. Nhóm Most 
    Significant 10 bits đuợc mapped vào một giá trị 10bit nằm trong khoảng từ 
    u+D800 đến u+DBFF. Nhóm Least Significant 10 bits đuợc mapped vào một giá 
    trị 10bit nằm trong khoảng từ u+DC00 đến u+DFFF. Theo cách đó UTF-16 có thể 
    biểu diễn được những characters Unicode có 20bits. </FONT><BR>
    <H4><FONT face=Tahoma color=blue>UTF-8</FONT></H4><FONT face=Tahoma>UTF-8 là 
    một cách encoding để có tác dụng y như UCS-4 (cũng là UTF-16), chớ không 
    phải có code point nào khác. UTF-8 được thiết kế cho upward-compatible với 
    ASCII. UTF-8 không phải là chỉ dùng một byte, nhưng là dùng nhiều bytes - từ 
    1 đến 6 bytes. <BR><BR>Cách hoán chuyển UTF-16 qua UTF-8 và ngược lại đuợc 
    làm theo bảng dưới đây. Trong Table dưới đây, những binary (Nhị phân) bits 
    nằm bên trái của UTF-16 đuợc chuyển qua bên phải của UTF-8 theo cùng một màu 
    như chỉ dẫn. Ta hãy thử lấy thí dụ chữ <FONT size=+1><B>ả</B></FONT> với 
    code point, hay UTF-16, <FONT size=+1><B>1EA3</B></FONT>. UTF-8 bytes của nó 
    là <B>E1BAA3</B>. Nếu bạn chưa quen cách dùng số nhị phân hay Hex hãy đọc 
    qua bài <A href="http://www.vovisoft.com/mcse/rks/tnt/binarynumber.htm">Hệ 
    thống số nhị phân</A>. <BR><BR>
    <BLOCKQUOTE>
      <BLOCKQUOTE><PRE><FONT face=courier>
     <B> UCS-4 (UTF-16) </B>         <B> UTF-8</B>
     1     E      A    3         1110 ????  10?? ????  10?? ????
     0001 1110   1010 0011       1110 0001  1011 1010  1010 0011   
                                 E     1     B    A     A    3
</FONT></PRE></BLOCKQUOTE></BLOCKQUOTE><FONT face=Courier size=3>
    <TABLE cellPadding=10 bgColor=#e8e8e8 border=2>
      <TBODY>
      <TR>
        <TD align=middle width="45%"><FONT size=+1><B>UTF-16 (Nhị 
          phân)</B></FONT></TD>
        <TD align=middle><FONT size=+1><B>UTF-8 (Nhị phân)</B></FONT></TD></TR>
      <TR>
        <TD width="40%">00000000 00000000 00000000 0<FONT 
          color=blue>???????</FONT></TD>
        <TD>0<FONT color=blue>???????</FONT></TD></TR>
      <TR>
        <TD>00000000 00000000 00000<FONT color=green>??? ??</FONT><FONT 
          color=blue>??????</FONT></TD>
        <TD>110<FONT color=green>?????</FONT> 10<FONT 
        color=blue>??????</FONT></TD></TR>
      <TR>
        <TD>00000000 00000000 <FONT color=red>????</FONT><FONT 
          color=green>???? ??</FONT><FONT color=blue>??????</FONT></TD>
        <TD>1110<FONT color=red>????</FONT> 10<FONT color=green>??????</FONT> 
          10<FONT color=blue>??????</FONT></TD></TR>
      <TR>
        <TD>00000000 000<FONT color=#00cc66>???</FONT><FONT color=red>?? 
          ????</FONT><FONT color=green>???? ??</FONT><FONT 
          color=blue>??????</FONT></TD>
        <TD>11110<FONT color=#00cc66>???</FONT> 10<FONT 
          color=red>??????</FONT> 10<FONT color=green>??????</FONT> 10<FONT 
          color=blue>??????</FONT></TD></TR>
      <TR>
        <TD>000000<FONT color=magenta>??</FONT> <FONT 
          color=#00cc66>??????</FONT><FONT color=red>?? ????</FONT><FONT 
          color=green>???? ??</FONT><FONT color=blue>??????</FONT></TD>
        <TD>111110<FONT color=magenta>??</FONT> 10<FONT 
          color=#00cc66>??????</FONT> 10<FONT color=red>??????</FONT> 10<FONT 
          color=green>??????</FONT> 10<FONT color=blue>??????</FONT></TD></TR>
      <TR>
        <TD>0<FONT color=#cc8822>?</FONT><FONT color=magenta>??????</FONT> 
          <FONT color=#00cc66>??????</FONT><FONT color=red>?? ????</FONT><FONT 
          color=green>???? ??</FONT><FONT color=blue>??????</FONT></TD>
        <TD>1111110<FONT color=#cc8822>?</FONT> 10<FONT 
          color=magenta>??????</FONT> 10<FONT color=#00cc66>??????</FONT> 
          10<FONT color=red>??????</FONT> 10<FONT color=green>??????</FONT> 
          10<FONT color=blue>??????</FONT></TD></TR>
      <TR></TR></TBODY></TABLE></FONT><BR>Trong chữ Việt, chúng ta chỉ làm việc 
    với một số tương đối ít Unicode code points ( tổng cộng 134 ký tự) và UTF-8, 
    bạn có thể hoặc dùng một Look-up table dựa theo <A 
    href="http://www.vovisoft.com/unicode/utilities/VietEncoding.htm">Bản đối 
    chiếu</A>, hoặc dùng hai <B>Functions ToUTF8 và ToUTF16</B> với Listings như 
    dưới đây để hoán chuyển từ encoding UTF-16 ra UTF-8, và ngược lại:<BR><BR>
    <BLOCKQUOTE>
      <TABLE bgColor=#f6f6f6>
        <TBODY>
        <TR>
          <TD><FONT size=3><PRE><FONT color=blue>Function</FONT> ToUTF8(<FONT color=blue>ByVal</FONT> UTF16 <FONT color=blue>As</FONT> Long) <FONT color=blue>As</FONT> Byte() 
   <FONT color=blue>' Convert a 16bit UTF-16BE to 2 or 3 UTF-8 bytes</FONT>
   <FONT color=blue>Dim</FONT> bArray() <FONT color=blue>As</FONT> <FONT color=blue>Byte</FONT> 
   <FONT color=blue>If</FONT> UTF16 &lt; &amp;H80 <FONT color=blue>Then</FONT> 
      <FONT color=blue>ReDim</FONT> bArray(0)  <FONT color=green>' one byte UTF-8</FONT>
      bArray(0) = UTF16  <FONT color=green>' Use number as is</FONT>
   <FONT color=blue>ElseIf</FONT> UTF16 &lt; &amp;H800 <FONT color=blue>Then</FONT> 
      <FONT color=blue>ReDim</FONT> bArray(1)  <FONT color=green>' two byte UTF-8</FONT>
      bArray(1) = &amp;H80 + (UTF16 <FONT color=blue>And</FONT> &amp;H3F)  <FONT color=green>' Least Significant 6 bits</FONT>
      UTF16 = UTF16 \ &amp;H40  <FONT color=green>' Shift UTF16 number right 6 bits</FONT>
      bArray(0) = &amp;HC0 + (UTF16 <FONT color=blue>And</FONT> &amp;H1F)  <FONT color=green>' Use 5 remaining bits</FONT>
   <FONT color=blue>Else</FONT> 
      <FONT color=blue>ReDim</FONT> bArray(2)  <FONT color=green>' three byte UTF-8</FONT>
      bArray(2) = &amp;H80 + (UTF16 <FONT color=blue>And</FONT> &amp;H3F)  <FONT color=green>' Least Significant 6 bits</FONT>
      UTF16 = UTF16 \ &amp;H40  <FONT color=green>' Shift UTF16 number right 6 bits</FONT>
      bArray(1) = &amp;H80 + (UTF16 <FONT color=blue>And</FONT> &amp;H3F)  <FONT color=green>' Use next 6 bits</FONT>
      UTF16 = UTF16 \ &amp;H40  <FONT color=green>' Shift UTF16 number right 6 bits again</FONT>
      bArray(0) = &amp;HE0 + (UTF16 <FONT color=blue>And</FONT> &amp;HF)  <FONT color=green>' Use 4 remaining bits</FONT>
   <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
   ToUTF8 = bArray  <FONT color=green>' Return UTF-8 bytes in an array</FONT>
<FONT color=blue>End</FONT> <FONT color=blue>Function</FONT> <BR><BR>
<FONT color=blue>Function</FONT> ToUTF16(bArray) <FONT color=blue>As</FONT> <FONT color=blue>Long</FONT> 
   <FONT color=green>' Convert 2 or 3 UTF-8 bytes to a 16bit UTF-16BE</FONT>
   <FONT color=blue>Dim</FONT> IntUB 
   IntUB = UBound(bArray)  <FONT color=green>' Find out how many bytes UTF-8 takes</FONT>
   <FONT color=blue>Select</FONT> <FONT color=blue>Case</FONT> IntUB 
   <FONT color=blue>Case</FONT> 0  <FONT color=green>' one byte UTF-8. Note that bArray starts with index=0</FONT>
      ToUTF16 = bArray(0)  <FONT color=green>' Use number as is</FONT>
   <FONT color=blue>Case</FONT> 1  <FONT color=green>' two byte UTF-8</FONT>
      ToUTF16 = (bArray(0) <FONT color=blue>And</FONT> &amp;H1F) * &amp;H40 + (bArray(1) <FONT color=blue>And</FONT> &amp;H3F) 
   <FONT color=blue>Case</FONT> 2  <FONT color=green>' three byte UTF-8</FONT>
      ToUTF16 = (bArray(0) <FONT color=blue>And</FONT> &amp;HF) * &amp;H1000 + (bArray(1) <FONT color=blue>And</FONT> &amp;H3F) * &amp;H40 + (bArray(2) <FONT color=blue>And</FONT> &amp;H3F) 
   <FONT color=blue>End</FONT> <FONT color=blue>Select</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Function</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE><BR>Thật ra hai 
    Functions ToUTF8 và ToUTF16 được viết ra để làm sáng tỏ cách hoán chuyển 
    giữa UTF-16 và UTF-8 mà thôi, vì trong .NET ta có thể tuyên bố 
    System.Text.Encoding để .NET tự động quản lý cách encoding cho chúng ta. 
    <P><B><I>Xin lưu ý:</I></B> Hình chữ <FONT face=Tahoma><FONT 
    size=3><B>Ð</B></FONT></FONT> có hai code points: <B>&amp;HD0</B> và 
    <B>&amp;H110</B>. Code point &amp;HD0 là của chữ Latin Eth hoa ( chữ Latin 
    Eth thường là <B><SPAN 
    style="FONT-FAMILY: Tahoma; mso-fareast-font-family: Times New Roman; mso-ansi-language: EN-AU; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><FONT 
    size=3>ð</FONT></SPAN></B><SPAN 
    style="FONT-SIZE: 12pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-AU; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">) 
    </SPAN>, còn code point &amp;H110 là của chữ Latin d hoa với stroke <FONT 
    face=Tahoma>( chữ Latin d thường với stroke là <FONT size=3><B><SPAN 
    style="FONT-FAMILY: Tahoma; mso-fareast-font-family: Times New Roman; mso-ansi-language: EN-AU; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">đ</SPAN></B></FONT><FONT 
    size=3><B><SPAN 
    style="FONT-FAMILY: Tahoma; mso-fareast-font-family: Times New Roman; mso-ansi-language: EN-AU; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"> 
    </SPAN></B></FONT><SPAN 
    style="FONT-SIZE: 12pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-AU; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">) 
    </SPAN></FONT>.&nbsp; Do đó ta phải dùng code point &amp;H110.&nbsp; Bạn có 
    thể copy chữ <FONT size=3><B>Ð</B></FONT> nầy ngay từ Browser để</FONT> 
    <FONT face=Tahoma>paste vào chỗ nào cần thiết. </P></FONT><BR></BLOCKQUOTE>
  <H3><FONT face=Tahoma color=blue>BOM (Byte Order Mark)</FONT></H3><FONT 
  face=Tahoma>Vì Unicode nói chung hỗ trợ UTF-16BE, UTF-16LE và UTF-8, nên để có 
  thể biết được Text file trong Microsoft Windows đang chứa Unicode encoding 
  kiểu nào, ở đầu mỗi Unicode Text file có 2 hay 3 bytes gọi là <B>Byte Order 
  Mark</B> như sau:<BR><BR>
  <BLOCKQUOTE>
    <BLOCKQUOTE>
      <TABLE cellPadding=10 bgColor=#e8e8e8 border=2>
        <TBODY>
        <TR>
          <TD><B>Character Encoding Scheme</B></TD>
          <TD><B>Byte Order Mark</B></TD></TR>
        <TR>
          <TD>UTF-16BE</TD>
          <TD>FE FF</TD></TR>
        <TR>
          <TD>UTF-16LE</TD>
          <TD>FF FE</TD></TR>
        <TR>
          <TD>UTF-8</TD>
          <TD>EF BB BF</TD></TR></TBODY></TABLE></BLOCKQUOTE></BLOCKQUOTE>Khi viết 
  Unicode ra Text file trong MSWindows, nếu dùng UTF-8 bạn chỉ cần viết ở đầu 
  file Byte Order Mark <B>EF BB BF</B>. Các bytes kế tiếp cứ theo đúng hoặc 
  UTF-8 characters thì dùng 2 hay 3 bytes hoặc ANSI characters thì dùng 1 
  byte.<BR>Nếu dùng UTF-16LE (còn gọi gọn là Unicode trong ngôn ngữ Microsoft) 
  thì viết Byte Order Mark <B>FF FE</B>. Kế đó mỗi character phải viết ra 2 
  bytes dù là Unicode hay không. Nếu character chỉ cần 1 byte, kể cả các 
  characters như Carriage Return (&amp;H0D) và LineFeed (&amp;H0A), thì viết 
  thêm byte thứ nhì là <B>00</B> (Null byte). Thí dụ:<BR>
  <BLOCKQUOTE>
    <BLOCKQUOTE>
      <TABLE cellPadding=10 bgColor=#e8e8e8 border=2>
        <TBODY>
        <TR>
          <TD><B>Character Encoding Scheme</B></TD>
          <TD><B>Các bytes viết ra Text file</B></TD></TR>
        <TR>
          <TD>Text của file</TD>
          <TD>á à ả</TD></TR>
        <TR>
          <TD>UTF-16LE</TD>
          <TD>FF FE E1 00 20 00 E0 00 20 00 A3 1E</TD></TR>
        <TR>
          <TD>UTF-8</TD>
          <TD>EF BB BF C3 A1 20 C3 A0 20 E1 BA 
    A3</TD></TR></TBODY></TABLE></BLOCKQUOTE></BLOCKQUOTE>Câu hỏi đặt ra là Text 
  File với encoding UTF-16LE hay UTF-8 chiếm nhiều chỗ hơn. Câu trả lời là tùy 
  theo trường hợp. Ðối với UTF-16 thì mỗi character cần 2 bytes, kể cả ANSI 
  characters. Ðối với UTF-8 thì nếu là Unicode character thì cần 2 hay 3 bytes, 
  còn ANSI character thì chỉ cần 1 byte.<BR></FONT>
  <H3><FONT face=Tahoma color=green>Làm việc với Unicode chữ Việt trong 
  .NET</FONT></H3>
  <H3><FONT face=Tahoma color=blue>Edit Unicode chữ Việt trong Visual Studio.NET 
  IDE</FONT></H3><FONT face=Tahoma>Visual Studio.NET IDE hỗ trợ chữ Việt Unicode 
  trong coding và comments của VB.NET và C#. Để đánh chữ Việt, bạn có thể dùng 
  VietKey, UniKey, VPSKey .v.v.. IDE sẽ lưu trữ code dưới dạng UTF-8 nếu bạn set 
  up <B>Advanced Save Option</B> từ Menu command <B>File</B> như trong hình dưới 
  đây:<BR><BR>
  <BLOCKQUOTE><IMG height=474 
    src="Can ban ve UNICODE tieng Viet_files/AdvancedSave.gif" 
  width=224></BLOCKQUOTE>Khi Dialog hiện ra, bạn chọn <B>Unicode (UTF-8 with hay 
  without signature)</B> cho <B>Encoding</B>: 
  <BLOCKQUOTE><IMG height=165 
    src="Can ban ve UNICODE tieng Viet_files/AdvancedSaveDialog.gif" 
  width=338></BLOCKQUOTE><BR>Nếu bạn không thấy có menuItem Advanced Save Option 
  trong Menu File thì cứ dùng menuItem <B>Save As...</B> rồi click lên combo box 
  <B>Save</B> phía dưới, bên phải của Save File As Dialog rồi chọn <B>Save with 
  Encoding...</B> như trong hình dưới đây:<BR><BR>
  <BLOCKQUOTE><IMG height=412 
    src="Can ban ve UNICODE tieng Viet_files/SaveWithEncoding.gif" 
  width=662></BLOCKQUOTE><BR>Nếu bạn quên set up Advanced Save Option như trên, 
  chữ Việt sẽ bị lưu trữ dưới dạng ANSI nên một số sẽ mất dấu chữ Việt và thay 
  vào đó bằng những dấu <B>?</B>. 
  <H3><FONT face=Tahoma color=blue>Đọc, viết Unicode text file</FONT></H3>Trong 
  thí dụ dưới đây, ta đọc một Unicode (UTF-16 little endian) text file và copy 
  nó vào một UTF-8 text file. Ta declare loại Encoding lúc instantiate 
  StreamReader hay StreamWriter.<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> BtnConvert_Click( <FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> BtnConvert.Click 
  <FONT color=green>' Instantiate a stream reader to read a Unicode (UTF16 little endian) text file</FONT>
  <FONT color=green>' from parent folder of Application.StartupPath</FONT>
   <FONT color=blue>Dim</FONT> rd <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> StreamReader("..\\" &amp; TextBox1.Text, System.Text.Encoding.Unicode) 
  <FONT color=green>' Instantiate a stream writer to write a UTF-8 text file</FONT>
  <FONT color=green>' False stands for "NOT Append", i.e. create new file or overwrite existing file</FONT>
   <FONT color=blue>Dim</FONT> wr <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> StreamWriter("..\\" &amp; TextBox1.Text.Substring(0, TextBox1.Text.Length - 4) &amp; "UTF8.txt",  _
                      False, System.Text.Encoding.UTF8) 
   <FONT color=blue>Dim</FONT> ALine <FONT color=blue>As</FONT> <FONT color=blue>String</FONT> 
  <FONT color=green>' Copy each line from input file to output file</FONT>
   ALine = rd.ReadLine 
   <FONT color=blue>Do</FONT> <FONT color=blue>While</FONT> <FONT color=blue>Not</FONT> ALine Is <FONT color=blue>Nothing</FONT> <FONT color=green>' Test End-of-File</FONT>
      wr.WriteLine(ALine) 
      ALine = rd.ReadLine 
   <FONT color=blue>Loop</FONT> 
   rd.Close() <FONT color=green>' Close input stream</FONT>
   wr.Close() <FONT color=green>' Close output stream</FONT>
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>Thật ra, .NET thông minh 
  đủ để nhận diện Encoding của input text file bằng cách đọc Byte Order Mark 
  (BOM). Do đó, thay vì declare encoding Unicode cho input file ta có thể bảo nó 
  auto-detect BOM bằng cách thay thế statement:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE>   <FONT color=blue>Dim</FONT> rd <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> StreamReader("..\\" &amp; TextBox1.Text, System.Text.Encoding.Unicode) 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>với statement:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE>   <FONT color=blue>Dim</FONT> rd <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> StreamReader("..\\" &amp; TextBox1.Text, True) 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>Chữ <B>True</B> có nghĩa 
  auto-detect Byte Order Mark để nhận diện encoding Unicode, UTF8, 
  BigEndianUnicode,.v.v..<BR><BR>Lưu ý là mặc dầu .NET không giới hạn việc ta 
  dùng Unicode, nhưng ta phải tuyên bố loại Encoding của output file rõ ràng, 
  nếu không, kết quả có thể là ANSI text, tức là một số characters có dấu của 
  chữ Việt sẽ bị hư (corrupted).<BR><BR>Một điểm nữa cần lưu ý là ở đây ta làm 
  việc với Stream, chớ không phải files. Stream có thể được áp dụng cho files 
  như ở đây, nhưng nó cũng có thể được áp dụng cho <B>Serialization</B>, tức là 
  gởi hay chứa data dưới dạng một chuỗi bytes. Công tác ngược lại của 
  Serialization là <B>Deserialization</B>, tức là nhận hay lấy ra data dưới dạng 
  một chuỗi bytes. Cho các trường hợp Serialization/ Deserialization (Xấy khô/ 
  Ngâm nước) ta cũng có thể dùng cách tuyên bố loại Encoding y như 
  trên.<BR><BR>Trong Sub BtnConvert_Click ở trên ta cũng có thể thay thế các 
  hàng code:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE>   <FONT color=blue>Dim</FONT> ALine <FONT color=blue>As</FONT> <FONT color=blue>String</FONT> 
  <FONT color=green>' Copy each line from input file to output file</FONT>
   ALine = rd.ReadLine 
   <FONT color=blue>Do</FONT> <FONT color=blue>While</FONT> <FONT color=blue>Not</FONT> ALine Is <FONT color=blue>Nothing</FONT> <FONT color=green>' Test End-of-File</FONT>
      wr.WriteLine(ALine) 
      ALine = rd.ReadLine 
   <FONT color=blue>Loop</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>bằng cách coding ngắn hơn 
  như sau:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE>   <FONT color=blue>Dim</FONT> OutputString <FONT color=blue>As</FONT> <FONT color=blue>String</FONT> 
  <FONT color=green>' Read input file right to the end</FONT>
   OutputString = rd.ReadToEnd
  <FONT color=green>' Write the lot to output file</FONT>
   wr.Write(OutputString )
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE><BR>Bạn có thể <A 
  href="http://www.vovisoft.com/dotNET/Support/UnicodeBasic/UnicodeToUTF8.zip">download 
  source code của program UnicodeToUTF8</A> nầy.<BR><BR>
  <H3><FONT face=Tahoma color=blue>Gởi và nhận byte buffers của 
  Unicode</FONT></H3><FONT face=Tahoma>Để <B>gởi</B> một Unicode Text string qua 
  mạng ta thường chuyển nó thành một byte buffer trước khi gởi đi. Quá trình nầy 
  gồm hai bước:<BR>
  <OL>
    <LI>Đổi Unicode Text string thành một array-of-characters, 
    <B>(mMessage.ToCharArray)</B> 
    <LI>Đổi Unicode array-of-characters thành một byte buffer, 
    <B>System.Text.Encoding.UTF8.GetBytes</B> </LI></OL>như trong thí dụ dưới 
  đây:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=blue>Dim</FONT> mMessage <FONT color=blue>As</FONT> <FONT color=blue>String</FONT> 
<FONT color=blue>Dim</FONT> Buffer() <FONT color=blue>As</FONT> <FONT color=blue>Byte</FONT> 
Buffer = System.Text.Encoding.UTF8.GetBytes(mMessage.ToCharArray) 
<FONT color=green>' Gởi byte buffer đi ...</FONT>
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE><BR>Khi <B>nhận</B> byte 
  buffer của một Unicode Text string, ta có thể dùng hàm 
  <B>System.Text.Encoding.UTF8.GetString</B> chuyển nó trở lại thành Unicode 
  Text string như sau:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=blue>Dim</FONT> RecvMessage <FONT color=blue>As</FONT> <FONT color=blue>String</FONT> 
<FONT color=blue>Dim</FONT> Buffer(5000) <FONT color=blue>As</FONT> <FONT color=blue>Byte</FONT> 
<FONT color=green>' Nhận byte buffer  ...</FONT>
RecvMessage = System.Text.Encoding.UTF8.GetString(Buffer) 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE><BR>Nếu ta không dùng 
  encoding UTF8 thì .NET có thể lẳng lặng dùng encoding.ASCII by default và vô 
  tình làm hư Unicode Text string.<BR>
  <H3><FONT face=Tahoma color=blue>Chứa Unicode text string vào Clipboard và lấy 
  nó ra</FONT></H3><FONT face=Tahoma><B>Chứa</B> một text string vào 
  Clipboard:<BR><BR>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=green>' Copy text string strData to clipboard</FONT>
Clipboard.SetDataObject(strData) 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE><BR><B>Lấy</B> Unicode 
  text string từ Clipboard gồm có hai bước: 
  <OL>
    <LI>Tạo một DataObject Interface với <B>Clipboard.GetDataObject()</B> 
    <LI>Dùng Interface ấy để lấy data từ Clipboard dưới dạng Unicode 
    (<B>DataFormats.UnicodeText</B>), rồi đổi nó ra string </LI></OL>
  <BLOCKQUOTE>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=green>' Create a new instance of the DataObject interface.</FONT>
<FONT color=blue>Dim</FONT> data <FONT color=blue>As</FONT> IDataObject = Clipboard.GetDataObject() 
<FONT color=green>' Retrieve Text string in Unicode Text format from clipboard</FONT>
strData = data.GetData(DataFormats.UnicodeText).ToString() 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE><BR><BR>
  <BLOCKQUOTE><A href="http://www.vovisoft.com/"><IMG height=40 
    src="Can ban ve UNICODE tieng Viet_files/homejump.gif" 
    width=40><A>&nbsp;&nbsp;<A 
    href="http://www.vovisoft.com/dotNET/default.asp">Học Microsoft 
    .NET</A><BR><BR></BLOCKQUOTE><BR></BLOCKQUOTE></FONT><!-- End of Cut and paste content --><!-- Start of bottom bar for copyright notice etc --><!-- End of Cut and paste content --><!-- Start of bottom bar for copyright notice etc -->
<TABLE class=clsNavLinks id=tblFooterLinks cellSpacing=0 cellPadding=0 
width="100%" border=0>
  <TBODY>
  <TR>
    <TD class=clsRaised width=785 bgColor=#6699cc colSpan=5>
      <P align=center><FONT face=Tahoma color=#ffffff size=1>Vovisoft Â© 2000. 
      All rights reserved.</FONT></P></TD></TR>
  <TR>
    <TD width=256>
      <P align=center><FONT face=Tahoma size=1>&nbsp;&nbsp; Last Updated: <!--webbot 
      bot="Timestamp" S-Type="REGENERATED" S-Format="%d %b %Y" startspan -->12 
      Feb 2002<!--webbot 
      bot="Timestamp" endspan i-checksum="14381" --> </FONT></P></TD>
    <TD width=181><FONT face=Tahoma size=1>&nbsp;</FONT></TD>
    <TD width=258>
      <P align=center><FONT face=Tahoma size=1><A 
      href="mailto:dixon@vovisoft.com">Webmaster</A></FONT></P></TD></TR></TBODY></TABLE><BR></A></FONT></FONT></BODY></HTML>
